package com.ruoyi.exam.service.impl;

import java.util.*;

import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.exam.mapper.DocumentCategoryMapper;
import com.ruoyi.exam.domain.DocumentCategory;
import com.ruoyi.exam.service.IDocumentCategoryService;

/**
 * 文档分类树状结构Service业务层处理
 * 
 * @author xiayuan
 * @date 2025-05-16
 */
@Service
public class DocumentCategoryServiceImpl implements IDocumentCategoryService 
{
    @Autowired
    private DocumentCategoryMapper documentCategoryMapper;

    /**
     * 查询文档分类树状结构
     * 
     * @param id 文档分类树状结构主键
     * @return 文档分类树状结构
     */
    @Override
    public DocumentCategory selectDocumentCategoryById(Long id)
    {
        return documentCategoryMapper.selectDocumentCategoryById(id);
    }

    /**
     * 查询文档分类树状结构列表
     * 
     * @param documentCategory 文档分类树状结构
     * @return 文档分类树状结构
     */
    @Override
    public List<DocumentCategory> selectDocumentCategoryList(DocumentCategory documentCategory)
    {
        List<DocumentCategory> documentCategories = documentCategoryMapper.selectDocumentCategoryList(documentCategory);
        return buildTreeWithSort(documentCategories);
    }

    /**
     * 新增文档分类树状结构
     * 
     * @param documentCategory 文档分类树状结构
     * @return 结果
     */
    @Override
    public int insertDocumentCategory(DocumentCategory documentCategory)
    {
        documentCategory.setCreateTime(DateUtils.getNowDate());
        return documentCategoryMapper.insertDocumentCategory(documentCategory);
    }

    /**
     * 修改文档分类树状结构
     * 
     * @param documentCategory 文档分类树状结构
     * @return 结果
     */
    @Override
    public int updateDocumentCategory(DocumentCategory documentCategory)
    {
        documentCategory.setUpdateTime(DateUtils.getNowDate());
        return documentCategoryMapper.updateDocumentCategory(documentCategory);
    }

    /**
     * 批量删除文档分类树状结构
     * 
     * @param ids 需要删除的文档分类树状结构主键
     * @return 结果
     */
    @Override
    public int deleteDocumentCategoryByIds(Long[] ids)
    {
        return documentCategoryMapper.deleteDocumentCategoryByIds(ids);
    }

    /**
     * 删除文档分类树状结构信息
     * 
     * @param id 文档分类树状结构主键
     * @return 结果
     */
    @Override
    public int deleteDocumentCategoryById(Long id)
    {
        return documentCategoryMapper.deleteDocumentCategoryById(id);
    }

    // 增加排序功能的构建方法
    public static List<DocumentCategory> buildTreeWithSort(List<DocumentCategory> nodes) {
        // 先按sortOrder排序（同级节点）
        nodes.sort(Comparator.comparing(DocumentCategory::getSortOrder));

        // 调用基础构建方法
        return buildTreeWithCycleDetection(nodes);
    }

    // 增加循环引用检测
    public static List<DocumentCategory> buildTreeWithCycleDetection(List<DocumentCategory> nodes) {
        Map<Long, DocumentCategory> nodeMap = new HashMap<>();
        List<DocumentCategory> roots = new ArrayList<>();
        Set<Long> processedIds = new HashSet<>();

        for (DocumentCategory node : nodes) {
            nodeMap.put(node.getId(), node);
        }

        for (DocumentCategory node : nodes) {
            if (processedIds.contains(node.getId())) {
                throw new IllegalArgumentException("检测到循环引用：" + node.getId());
            }
            buildNodeTree(node, nodeMap, processedIds);
            if (node.getParentId() == null) {
                roots.add(node);
            }
        }
        return roots;
    }

    private static void buildNodeTree(DocumentCategory node,
                                      Map<Long, DocumentCategory> nodeMap,
                                      Set<Long> processedIds) {
        processedIds.add(node.getId());
        if (node.getParentId() != null) {
            DocumentCategory parent = nodeMap.get(node.getParentId());
            if (parent != null) {
                ensureChildrenInitialized(parent);
                parent.getChildren().add(node);
                buildNodeTree(parent, nodeMap, processedIds); // 递归处理父节点
            }
        }
    }

    /**
     * 确保节点的children集合已初始化
     */
    private static void ensureChildrenInitialized(DocumentCategory node) {
        if (node.getChildren() == null) {
            node.setChildren(new ArrayList<>());
        }
    }
}
